﻿

using System;
using System.Threading;
using System.Diagnostics;

namespace Demo.Infrastructure.Test
{
    class Program
    {
        static void Main(string[] args)
        {
            //第一种创建常用方法
            //Thread thread0 = new Thread(Print0);
            //thread0.Start();

            //第二种创建常用方法
            //Thread thread1 = new Thread(Print1);
            //thread1.Start("Y");

            //第三种创建常用方法
            //Thread thread11 = new Thread(() => Print1("X"));
            //thread11.Start();

            //线程临时变量 分配独立的栈--每条线程有自己的执行路径
            //Thread thread2 = new Thread(() => Print2());
            //thread2.Start();
            //Thread thread21 = new Thread(() => Print2());
            //thread21.Start();
            //临时变量 以及线程名称
            //Print21();

            //Thread thread1 = new Thread(obj1);
            //thread1.Start();
            //Thread thread2 = new Thread(obj2);
            //thread2.Start();

            TimesDemo02.Init(0, 300);


            Console.ReadLine(); 
        }

        #region

        static void Print0()
        {
            for (int i = 1; i <= 100; i++)
            {
                if(i % 4 == 0)
                    Console.WriteLine( i.ToString() + "\t");
                else
                    Console.Write(i.ToString() + "\t");
            }
        }

        static void Print1(object message)
        {
            for (int i = 0; i < 100;i++ )
            {
                if (i % 4 == 0)
                    Console.WriteLine(message as string + "_" + i.ToString() + "\t");
                else
                    Console.Write(message as string + "_" + i.ToString() + "\t");
            }
        }

        static void Print2()
        {
            var str = Guid.NewGuid();
            Console.WriteLine(str);
        }

        static void Print210(string str)
        {
            Console.WriteLine(Thread.CurrentThread.Name + "_" +  str);
        }

        static void Print21()
        { 
            for(int i=0;i<4;i++)
            {
                var temp = i;
                Thread t = new Thread(() => Print210(temp.ToString()));
                t.Name = temp.ToString();
                t.Start();
            }
        }

        static object1 obj11 = new object1();
        static object2 obj22 = new object2();

        static cla cla = new cla();

        static void obj1()
        {
            //lock (obj11)
            //{
            //    Sleep();
            //    ++obj11.i;
            //    Console.WriteLine("1-obj11 开始锁定" + obj11.i);
            //    lock(obj22)
            //    {
            //        ++obj22.i;
            //        Console.WriteLine("1-obj22 开始锁定" + obj22.i);
            //    }
            //}
            //lock (cla)
            //{
            //    Sleep();
            //    ++cla.obj11.i;
            //    Console.WriteLine("1-obj11 开始锁定" + cla.obj11.i);
            //    ++cla.obj22.i;
            //    Console.WriteLine("1-obj22 开始锁定" + cla.obj22.i);
            //}

            Monitor.Enter(cla);
            Sleep();
            ++cla.obj11.i;
            Console.WriteLine("1-obj11 开始锁定" + cla.obj11.i);
            ++cla.obj22.i;
            Console.WriteLine("1-obj22 开始锁定" + cla.obj22.i);
            Monitor.Exit(cla);
        }

        static void obj2()
        {
            //lock (obj22)
            //{
            //    Sleep();
            //    ++obj22.i;
            //    Console.WriteLine("2-obj22 开始锁定" + obj22.i);
            //    lock (obj11)
            //    {
            //        ++obj11.i;
            //        Console.WriteLine("2-obj11 开始锁定" + obj11.i);
            //    }
            //}
            //lock (cla)
            //{
            //    Sleep();
            //    ++cla.obj22.i;
            //    Console.WriteLine("2-obj22 开始锁定" + cla.obj22.i);
            //    ++cla.obj11.i;
            //    Console.WriteLine("2-obj11 开始锁定" + cla.obj11.i);
            //}
            Monitor.Enter(cla);
            Sleep();
            ++cla.obj22.i;
            Console.WriteLine("2-obj22 开始锁定" + cla.obj22.i);
            ++cla.obj11.i;
            Console.WriteLine("2-obj11 开始锁定" + cla.obj11.i);
            Monitor.Exit(cla);
        }
        static void Sleep()
        { 
            Thread.Sleep(100);
        }

        #endregion
    }

    #region 定时器实例

    /// <summary>
    /// 不安全定时器；执行次数受到代码执行延时产生执行次数增多的不安全现象
    /// </summary>
    public class TimesDemo01
    {
        /// <summary>
        /// 定时器实例
        /// </summary>
        static System.Threading.Timer Time;

        /// <summary>
        /// 定时器延时时间
        /// </summary>
        static Int32 DelayTime;

        /// <summary>
        /// 定时器间隔时间
        /// </summary>
        static Int32 IntervalTime;

        /// <summary>
        /// 定时器共享变量
        /// </summary>
        static Int32 Count;

        /// <summary>
        /// 对象锁
        /// </summary>
        static object ObjLock = new object();

        public static void Init(Int32 delayTime, Int32 intervalTime)
        {
            ThreadPool.SetMaxThreads(100, 10);
            DelayTime = delayTime;
            IntervalTime = intervalTime;
            Time = new Timer(Execute, null, DelayTime, IntervalTime);
        }

        static void Execute(object obj)
        {
            Console.WriteLine("定时器:开始。上一次" + Count + "次");
            Thread.Sleep(1000);    //此时模拟代码执行时间，此睡眠值越大结果打印次数相差越大
            lock (ObjLock)
            {
                Count++;
            }
            if (Count == 80)
            {
                Console.WriteLine("\t定时器：打印" + Count + "次；此时停止");
                Time.Dispose();
            }
            else
                Console.WriteLine("\t定时器：打印" + Count + "次；");

            Console.WriteLine("定时器:结束。下一次" + Count + "次");
        }

    }

    public class TimesDemo02
    {
        /// <summary>
        /// 定时器实例
        /// </summary>
        static System.Threading.Timer Time;

        /// <summary>
        /// 定时器延时时间
        /// </summary>
        static Int32 DelayTime;

        /// <summary>
        /// 定时器间隔时间
        /// </summary>
        static Int32 IntervalTime;

        /// <summary>
        /// 定时器共享变量
        /// </summary>
        static Int32 Count;

        /// <summary>
        /// 对象锁
        /// </summary>
        static object ObjLock = new object();

        public static void Init(Int32 delayTime, Int32 intervalTime)
        {
            ThreadPool.SetMaxThreads(100, 10);
            DelayTime = delayTime;
            IntervalTime = intervalTime;
            Time = new Timer(Execute, null, DelayTime, IntervalTime);
        }

        static void Execute(object obj)
        {
            lock (ObjLock)
            {
                Console.WriteLine("定时器:开始。上一次" + Count + "次");
                Thread.Sleep(500);    //此时模拟代码执行时间，此睡眠值越大结果打印次数相差越大
                Count++;
                if (Count == 10)
                {
                    Console.WriteLine("\t定时器：打印" + Count + "次；此时停止");
                    Time.Dispose();
                }
                else
                    Console.WriteLine("\t定时器：打印" + Count + "次；");

                Console.WriteLine("定时器:结束。下一次" + (Count + 1) + "次");
            }
        }

    }

    #endregion


    class cla
    {
        public object1 obj11 = new object1();
        public object2 obj22 = new object2();
    }

    class object1
    {
        public Int32 i;
    }


    class object2
    {
        public Int32 i;
    }



}
